package com.hanliy.controller;

import cn.hutool.core.util.IdUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author hanyulin
 * @apiNote
 * @date 2021/12/17 14:25
 */
@RestController
@Api(tags = "阿里云临时凭证STS相关")
@RequestMapping(value = "/sts")
public class TestStsController {

    @Value("${storage.aliyun.endpoint}")
    private String endpoint;
    @Value("${storage.aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${storage.aliyun.accessKeySecret}")
    private String accessKeySecret;
    @Value("${storage.aliyun.bucketName}")
    private String bucketName;
    @Value("${storage.aliyun.roleArn}")
    private String roleArn ;

    /**
     * 自定义角色会话名称，用来区分不同的令牌，例如可填写为SessionTest。
     */
    @GetMapping
    @ApiOperation(value = "获取临时凭证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleSessionName", value = "角色会话名称,区分不同的令牌", required = true, paramType = "query", dataType = "String")
    })
    public AssumeRoleResponse testRole(@RequestParam("roleSessionName") String roleSessionName) {
        // https://help.aliyun.com/document_detail/100624.htm?spm=a2c4g.11186623.0.0.47e61e580EFCUy#concept-xzh-nzk-2gb
        /*
         * 构建一个阿里云客户端，用于发起请求。
         * 构建阿里云客户端时需要设置AccessKey ID和AccessKey Secret。
         */
        DefaultProfile profile = DefaultProfile.getProfile("cn-beijing",accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        /*
         * 构造请求，设置参数。关于参数含义和设置方法，请参见《API参考》。 RoleArn 和 RoleSessionName 为必填写项
         */
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setRegionId("cn-hangzhou");
        request.setRoleArn(roleArn);
        request.setRoleSessionName(roleSessionName);
        // 设置临时访问凭证的有效时间为3600秒。
        //request.setDurationSeconds(36000L);

        //发起请求，并得到响应。
        try {
            AssumeRoleResponse response = client.getAcsResponse(request);
            System.out.println(new Gson().toJson(response));
            return response;
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            System.out.println("ErrCode:" + e.getErrCode());
            System.out.println("ErrMsg:" + e.getErrMsg());
            System.out.println("RequestId:" + e.getRequestId());
        }
        return null;
    }

    @PostMapping("/upload")
    @ApiOperation(value = "测试使用临时凭证实现上传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "securityToken", value = "安全令牌", required = true, dataType = "String" , paramType = "query"),
            @ApiImplicitParam(name = "accessKeyId", value = "accessKey", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "accessKeySecret", value = "accessKeySecret", required = true, dataType = "String", paramType = "query")
    })
    public String update(@RequestParam String securityToken,
                         @RequestParam String accessKeyId,
                         @RequestParam String accessKeySecret,
                         @RequestParam MultipartFile file ){
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
        // 将文件上传至目标存储空间bucketName下的目录testDir下，PS：此处应该对文件名称做处理，避免重复
        String fileName = null;
        try{
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
            fileName = IdUtil.fastUUID() + "." + suffix;
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, "testDir/" + fileName ,file.getInputStream());
            ossClient.putObject(putObjectRequest);
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
        return "https://" + bucketName + "." + endpoint + "/testDir/" + fileName;
    }
}
